<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2017/11/20
 * Time: 13:19
 */
namespace App\Http\Controllers\Api;
use App\Helpers\Api\ApiResponse;
use App\Http\Controllers\Controller;
use App\Models\Addressee;
use App\Models\Machine;
use App\Models\MsgTaskLog;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpFoundation\Response as FoundationResponse;
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\HttpException;
class GetTaskController extends ApiController
{
    /**
     * @apiPermission none
     * @apiPermission anyone
     * @apiGroup GetTask
     * @api {get} /api/v1/getTask 获取消息任务
     * @apiName getTask
     * @apiVersion 1.0.0
     * @apiDescription app 获取消息任务
     * @apiParam {String} machine 机器码
     * @apiParam {String} email 账号邮箱
     * @apiParam {String} serial 设备serial
     * @apiSuccess {json} Success-Response:
     * { "result": "测试" ,"status_code":0}
     * @apiSampleRequest /api/v1/getTask
     */
    public function getTask(Request $request)
    {
        try {
            $this -> apiValidate($request , [
                'machine' => "required",
            ]);
                $machine = $request->get("machine");
                $redis = app("redis");
                $deviceKey = "msg:device:machine:" . $machine;
                // 查询今日完成任务数量
                $device_limit = $redis->get($deviceKey);
                $msg_task_device_limit = $redis->hget("config:msg_task_device_limit", "value");
                //获取设备活跃有效时间
                $deviceLiveExpire = $redis->hget("config:app_device_active_expire", "value");
                if ($deviceLiveExpire == 0) {
                    $deviceLiveExpire = 10;
                }
//                if ($device_limit >= $msg_task_device_limit) {
//                    return $this->error("该设备已完成今日任务");
//                }
                $fp = fopen("getmsg.txt", "w");
                if (!flock($fp, LOCK_EX)) {
                    return $this->error("系统繁忙，请稍后再试");
                }
                $msgTasksKeys = $redis->keys("dispatch:msgTask:*");

                if (!$msgTasksKeys) {
                    flock($fp, LOCK_UN);
                    return $this->error("任务为空");
                }
                $max_addressee = $redis->hget("config:max_addressee", "value");
                $data = [];
                foreach ($msgTasksKeys as $msgTasksKey) {
                    $msgTask = $redis->hgetall($msgTasksKey);
                    //add 状态不是1 和不能用的过滤掉
                    if (isset($msgTask['status']) && $msgTask['status'] != 1) {
                        continue;
                    }
                    if (isset($msgTask['enable']) && $msgTask['enable'] != 1) {
                        continue;
                    }
                    if ($msgTask['current_num'] >= $msgTask['target_num']) {
                        continue;
                    }
                    //当前此任务所用的设备数
//                    $current_limit = Machine::where("msg_task_id", $msgTask['id'])->count();
//                    if ($current_limit >= $msgTask['max_device_num']) {
//                        $is_run_task = Machine::where("msg_task_id", $msgTask['id'])->where("machine", $machine)->get();
//                        if ($is_run_task->isEmpty()) {
//                            continue;
//                        }
//                    }
                    $address_key = "msg:app-enable-account:" . $msgTask['id'];
                    if ($msgTask['current_num'] + $max_addressee >= $msgTask['target_num']) {
                        $max_addressee = $msgTask['target_num'] - $msgTask['current_num'];
                    }
                    $addressee = [];
                    for ($i =0 ; $i < $max_addressee ; $i ++)
                    {
                        $addressee[] = $redis -> spop($address_key);
                    }
                    if ($addressee) {
                        $redis->srem($address_key , $addressee);
                    }
                    if(count($addressee) == 0){
                        flock($fp, LOCK_UN);
                        return $this->error("收信人为空");
                    }
                    $data = [
                        'msg_task_id' => $msgTask['id'],
                        'msg_name' => $msgTask['name'],
                        'msg_content' => $msgTask['content'],
                        'msg_urls' => $msgTask['urls'],
                        'msg_link' => $msgTask['link'],
                        'ip' =>$msgTask['ip'],
                        'port'=>$msgTask['port'],
                        'num' => $max_addressee,
                        'addressee' => $addressee
                    ];
                    if ($data) {
                        //把机器和任务id绑定了
                        Machine::firstOrCreate([
                            'msg_task_id' => $msgTask['id'],
                            'machine' => $machine
                        ]);
                        break;
                    }
                }
                flock($fp, LOCK_UN);
                return $this->success($data);
        } catch (\Exception $e) {
            return $this -> error($e ->getTrace());
        }
    }

    /**
     * @apiPermission none
     * @apiPermission anyone
     * @apiGroup GetTask
     * @api {get} /api/v1/replyTask 消息任务回执
     * @apiName replyTask
     * @apiVersion 1.0.0
     * @apiDescription app 消息任务回执
     * @apiParam {String} machine 机器码
     * @apiParam {String} task_id 任务id
     * @apiParam {String} serial 设备serial
     * @apiParam {String} email 账号邮箱
     * @apiParam {String} addressee 收信人邮箱
     * @apiParam {String} status 0 成功 1 失败
     * @apiParam {String} log 日志
     * @apiSuccess {json} Success-Response:
     * { "result": "测试" ,"status_code":0}
     * @apiSampleRequest /api/v1/replyTask
     */
    public function replyTask(Request $request){
        try {
            $fp = fopen("replymsg.txt", "w");
            if (!flock($fp, LOCK_EX)) {
                return $this->error("系统繁忙，请稍后再试");
            }
            $task_id = $request->get("task_id");
            $machine = $request->get("machine");
            $msg_device_version = $request->get("msg_device_version");
            $task_key = "dispatch:msgTask:" . $task_id;
            $redis = app("redis");
            if($request->get("status")==0 ){
                $redis->HINCRBY($task_key, "current_num" , 1);
            }
            $deviceKey = "msg:device:" . $machine;
            $redis->incr($deviceKey);
            if($request->get("addressee")){
                DB::table("addressee")->where("number",$request -> get("addressee"))->increment('num');
            }
            $log = "msg:log:" .$request->get("task_id").":".$request->get("addressee").":".$request->get("status");
            $logs['status']=$request->get("status");
            $logs['msg_task_id']=$task_id;
            $logs['deviced_sn']=$request->get("serial");
            $logs['account_email']= $request->get("email");
            $logs['msg_device_name']=$machine;
            $logs['msg_device_version']=$msg_device_version;
            $logs['log']=$request->get("log","");
            $logs['addressee']=$request->get("addressee");
            $logs['current_at']=Carbon::now();
            $redis -> hmset($log , $logs);
            $deviceLiveExpire= $redis -> hget("config:app_device_active_expire" , "value");
            if($deviceLiveExpire== 0){
                $deviceLiveExpire =10;
            }
            //更新设备活跃记录
            $onlineDeviceLogKey ="app:online-device:" . $machine . ":" .$task_id;
            $redis ->hset($onlineDeviceLogKey,"machine",$machine);
            $redis ->hset($onlineDeviceLogKey,"task_id",$task_id);
            $redis->expire($onlineDeviceLogKey,$deviceLiveExpire*60);
            //更新设备状态
            $deviceDataKey = "app:device:" . $machine;
            $redis->hset($deviceDataKey,"name",$machine);
            $redis->hset($deviceDataKey,"status",1);
            $redis->hset($deviceDataKey,"last_active_time",time());
            //设备码和账号加1(如果需要走数据库吧)
//            $account =$redis->keys("msg:account:*:".$request->get("email"));
//                if($account){
//                    $acc =$account[0];
//                    $redis->HINCRBY($acc, "num" , 1);
//                }
//            $code =$redis->keys("msg:device:*:*:".$request->get("serial"));
//            if($code){
//                $co =$code[0];
//                $redis->HINCRBY($co, "num" , 1);
//            }
            flock($fp, LOCK_UN);
            return $this -> success("回调成功");
        } catch (\Exception $e) {
            return $this -> error($e -> getMessage());
        }

    }
}